package com.zsyg.common.util;

import com.github.pagehelper.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.SerializationUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author: create by YangWanLi
 * @version: v1.0
 * @description: redis工具类r
 * @date:2018/11/2
 */
@Component
public class RedisUtil implements  InitializingBean{

        private static Logger logger = LoggerFactory.getLogger(RedisUtil.class);

        //Redis服务器IP
        @Value("${spring.redis.host}")
        private  String ADDR;

        //Redis的端口号
        @Value("${spring.redis.port}")
        private  int PORT;

        //访问密码
        @Value("${spring.redis.password}")
        private  String AUTH;

        //可用连接实例的最大数目，默认值为8；
        //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
        @Value("${spring.redis.jedis.pool.max-active}")
        private  int MAX_ACTIVE;

        //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值也是8。
        @Value("${spring.redis.jedis.pool.max-idle}")
        private  int MAX_IDLE;

        //等待可用连接的最大时间，单位毫秒，默认值为-1，表示永不超时。如果超过等待时间，则直接抛出JedisConnectionException；
        @Value("${spring.redis.jedis.pool.max-wait}")
        private  int MAX_WAIT;

        @Value("${spring.redis.timeout}")
        private  int TIMEOUT;

        //在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
        private static boolean TEST_ON_BORROW = true;

        private static JedisPool jedisPool = null;



        /**
         * 获取Jedis实例
         * @return
         */
        public synchronized static Jedis getJedis() {
                try {
                        if (jedisPool != null) {
                                Jedis resource = jedisPool.getResource();
                                return resource;
                        } else {
                                return null;
                        }
                } catch (Exception e) {
                        e.printStackTrace();
                        return null;
                }
        }

        /**
         * 释放jedis资源
         * @param jedis
         */
        public static void returnResource(final Jedis jedis) {
                if (jedis != null) {
                        jedisPool.returnResource(jedis);
                }
        }

        /**
         * 获取redis键值-object
         *
         * @param key
         * @return
         */
        public static Object getObject(String key) {
                Jedis jedis = null;
                try {
                        jedis = jedisPool.getResource();
                        byte[] bytes = jedis.get(key.getBytes());
                        if(!StringUtils.isEmpty(bytes)) {
                                return SerializationUtils.deserialize(bytes);
                        }
                } catch (Exception e) {
                        logger.error("getObject获取redis键值异常:key=" + key + " cause:" + e.getMessage());
                } finally {
                        jedis.close();
                }
                return null;
        }

        /**
         * 设置redis键值-object
         * @param key
         * @param value
         * @return
         */
        public static String setObject(String key, Object value) {
                Jedis jedis = null;
                try {
                        jedis = jedisPool.getResource();
                        return jedis.set(key.getBytes(), SerializationUtils.serialize(value));
                } catch (Exception e) {
                        logger.error("setObject设置redis键值异常:key=" + key + " value=" + value + " cause:" + e.getMessage());
                        return null;
                } finally {
                        if(jedis != null)
                        {
                                jedis.close();
                        }
                }
        }

        public static String setObject(String key, Object value,int expiretime) {
                String result = "";
                Jedis jedis = null;
                try {
                        jedis = jedisPool.getResource();
                        result = jedis.set(key.getBytes(), SerializationUtils.serialize(value));
                        if(result.equals("OK")) {
                                jedis.expire(key.getBytes(), expiretime);
                        }
                        return result;
                } catch (Exception e) {
                        logger.error("setObject设置redis键值异常:key=" + key + " value=" + value + " cause:" + e.getMessage());
                } finally {
                        if(jedis != null)
                        {
                                jedis.close();
                        }
                }
                return result;
        }

        /**
         * 删除key
         */
        public static Long delkeyObject(String key) {
                Jedis jedis = null;
                try {
                        jedis = jedisPool.getResource();
                        return jedis.del(key.getBytes());
                }catch(Exception e) {
                        e.printStackTrace();
                        return null;
                }finally{
                        if(jedis != null)
                        {
                                jedis.close();
                        }
                }
        }

        public static Boolean existsObject(String key) {
                Jedis jedis = null;
                try {
                        jedis = jedisPool.getResource();
                        return jedis.exists(key.getBytes());
                }catch(Exception e) {
                        e.printStackTrace();
                        return null;
                }finally{
                        if(jedis != null)
                        {
                                jedis.close();
                        }
                }
        }


        /**
         * 设置hash数据类型
         */
        public static Long hset(String key, String item, Object value) {
                if (StringUtil.isNotEmpty(key) && StringUtil.isNotEmpty(key)) {
                        Jedis jedis =null;
                        try {
                                jedis = jedisPool.getResource();
                                return jedis.hset(key.getBytes(), item.getBytes(), SerializationUtils.serialize(value));
                        } catch (Exception e) {
                                return null;
                        }finally{
                                if(jedis != null)
                                {
                                        jedis.close();
                                }
                        }
                } else {
                        return null;
                }
        }


        /**
         * 获取hash数据类型
         */
        public static Object hget(String key, String item) {
                if (StringUtil.isNotEmpty(key) && StringUtil.isNotEmpty(key)) {
                        Jedis jedis =null;
                        try {
                                jedis = jedisPool.getResource();
                                return SerializationUtils.deserialize(jedis.hget(key.getBytes(), item.getBytes()));
                        } catch (Exception e) {
                                return null;
                        }finally{
                                if(jedis != null)
                                {
                                        jedis.close();
                                }
                        }
                } else {
                        return null;
                }
        }

        public  static Long incr(String key){
                if (StringUtil.isNotEmpty(key) && StringUtil.isNotEmpty(key)) {
                        Jedis jedis =null;
                        try {
                                jedis = jedisPool.getResource();
                                return jedis.incr(key);
                        } catch (Exception e) {
                                return -1L;
                        }finally{
                                if(jedis != null)
                                {
                                        jedis.close();
                                }
                        }
                } else {
                        return -1L;
                }
        }

        @Override
        public void afterPropertiesSet() throws Exception {
                try {
                        JedisPoolConfig config = new JedisPoolConfig();
                        config.setMaxTotal(MAX_ACTIVE);
                        config.setMaxIdle(MAX_IDLE);
                        config.setMaxWaitMillis(MAX_WAIT);
                        config.setTestOnBorrow(TEST_ON_BORROW);
                        jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }
}